import logging

from django.shortcuts import render

# Create your views here.
from fdfs_client.client import get_tracker_conf, Fdfs_client
from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet, GenericViewSet, ReadOnlyModelViewSet, ViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_404_NOT_FOUND, HTTP_400_BAD_REQUEST, HTTP_500_INTERNAL_SERVER_ERROR, HTTP_403_FORBIDDEN

from config.fastdfsConfig import FASTDFS_SERVER_DOMAIN
from promote.settings import alipay
from shopping.models import Classification
from users.utils import MyPermission
from utils.permissions import create_auto_user, update_auto_user, destroy_auto_user
from .serializers import *


class ClassificationViewSet(ModelViewSet):
    queryset = Classification.objects.filter(parent=None, is_delete=False)
    serializer_class = ParentClassificationSerializer
    permission_classes = [MyPermission]


class ClassificationStudentViewSet(GenericViewSet, ListModelMixin):
    queryset = Classification.objects.filter(parent=None, is_delete=False)
    serializer_class = ParentClassificationSerializer
    permission_classes = [IsAuthenticated]

    @action(methods=['get'], detail=True)
    def commodity(self, request, pk):
        try:
            classification = Classification.objects.filter(is_delete=False).get(id=pk)
        except Classification.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)
        
        classification_attr = 'classification1'
        classification_name = classification.name
        if classification.parent:
            classification_attr = 'classification2'
            classification_name = f'{classification.parent.name}---{classification.name}'
        data = getattr(classification, classification_attr).filter(is_delete=False)
        return Response({'classification': classification_name, 'commodity': CommoditySerializer(data, many=True).data})


# 导入日志器
logger = logging.getLogger(__name__)

tracker_path = get_tracker_conf('utils/fastdfs/client.conf')
client = Fdfs_client(tracker_path)


class CommodityViewSet(ModelViewSet):
    queryset = Commodity.objects.filter(is_delete=False)
    serializer_class = CommoditySerializer
    permission_classes = [MyPermission]

    @action(methods=['post'], detail=True)
    def img(self, request, pk):
        try:
            commodity = self.get_queryset().get(id=pk)
        except Commodity.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        # 获取请求中的文件数据，处理文件
        files = request.FILES.get('file')
        if not files or files.content_type not in ('image/jpeg', 'image/gif', 'image/png'):
            logger.info('商品获取失败')
            return Response(status=HTTP_400_BAD_REQUEST)
        try:
            image_ext_name = files.name.split('.')[-1]
        except Exception as e:
            logger.info('商品后缀名异常：{}'.format(e))
            image_ext_name = 'png'

        try:
            upload_res = client.upload_by_buffer(files.read(), file_ext_name=image_ext_name)
        except Exception as e:
            logger.info('商品上传异常：{}'.format(e))
            return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            if upload_res.get('Status') != 'Upload successed.':
                logger.info('商品上传到FastDFS服务器失败')
                return Response(status=HTTP_500_INTERNAL_SERVER_ERROR)
            else:
                image_name = upload_res.get('Remote file_id').decode()
                image_url = FASTDFS_SERVER_DOMAIN + image_name

                CommodityImg.objects.create(src=image_url, commodity=commodity)
                return Response({'data': image_url})


class CommodityStudentViewSet(GenericViewSet, RetrieveModelMixin):
    queryset = Commodity.objects.filter(is_delete=False, status=1)
    serializer_class = CommoditySerializer
    permission_classes = [IsAuthenticated]

    @action(methods=['get'], detail=False)
    def optimization(self, request):
        queryset = self.get_queryset().order_by('-comments').order_by('-create_time')
        if len(queryset) >= 5:
            queryset = queryset[:5]
        return Response(self.get_serializer(queryset, many=True).data)


class ShoppingCartViewSet(ModelViewSet):
    serializer_class = ShoppingCartSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.request.user.shoppingcart_set.all()

    @create_auto_user
    def create(self, request, *args, **kwargs):
        return ModelViewSet.create(self, request, *args, **kwargs)

    @update_auto_user(ShoppingCart)
    def update(self, request, *args, **kwargs):
        return ModelViewSet.update(self, request, *args, **kwargs)

    @destroy_auto_user(ShoppingCart)
    def destroy(self, request, *args, **kwargs):
        return ModelViewSet.destroy(self, request, *args, **kwargs)


class OrderViewSet(ReadOnlyModelViewSet, CreateModelMixin):
    serializer_class = OrderSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        return self.request.user.order_set


class PaymentViewSet(ViewSet):
    def retrieve(self, request, pk):
        # 获取到对应订单
        try:
            order = Order.objects.get(order_id=pk, user=request.user, status=1)
        except Order.DoesNotExist:
            return Response(status=HTTP_404_NOT_FOUND)

        # 需要跳转的支付页面
        order_string = alipay.api_alipay_trade_page_pay(
            # 订单号
            out_trade_no=order.order_id,
            # 金额
            total_amount=str(order.total_amount),  # 交易金额
            # 商品描述
            subject='PROMOTE系统%s' % order.order_id,
            # 回调地址
            return_url='http://localhost:8080/home/order/success',
        )
        pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string

        return Response({'pay_url': pay_url})

    def update(self, request):
        # 获取前端支付宝会调过来的数据
        query_dict = request.query_params
        # query_dict类型转字典，移除sign进行验证
        data = query_dict.dict()
        try:
            sign = data.pop('sign')
        except KeyError:
            return Response(HTTP_400_BAD_REQUEST)
        # 调用支付宝验证方法进行验证
        res = alipay.verify(data, sign)
        if not res:
            return Response(status=HTTP_403_FORBIDDEN)
        # 取出订单编号，取出支付宝交易号
        order_id = data.get('out_trade_no')
        trade_no = data.get('trade_no')
        # 存储到mysql之中
        Payment.objects.create(order_id=order_id, trade_id=trade_no)
        # 修改订单状态
        Order.objects.filter(order_id=order_id, status=1).update(status=2)

        return Response({'order_id': order_id, 'trade_id': trade_no})